
//模块初始化头文件
#include <linux/module.h>
//文件系统头文件　  filesystem
#include <linux/fs.h>
#include <mach/gpio.h>
//字符设备头文件  character device
#include <linux/cdev.h>
#include "7102_led.h"
#include <asm/uaccess.h>

#include <linux/device.h>
#include <linux/miscdevice.h>        //杂设备头文件





#define   led_major  0
#define   led_mijor  3
#define   led_jorcmt 5

#define LED_NAME  "gk7102_led"
char itk_buf[100] = {0};
//static struct cdev  itkdevice ; //用全局变量，不用分配空间

#define ITKMISC     "itkmisc"
#define itkmisc_mimor  131


extern void gk_gpio_set_out(u32 pin, u32 value);


//int (*open) (struct inode *, struct file *);
int itkled_open(struct inode *itkinode, struct file *itkfile)
{
	printk(KERN_INFO "itk open\n");

	return 0;
}

//ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t itkled_read(struct file *itkfile, char __user *itkuser, size_t itklen, loff_t *itkloff)
{
    unsigned long ret = 0;
    
	printk(KERN_INFO "itk read\n");
    ret = copy_to_user(itkuser, itk_buf, itklen);
    if(ret !=0)
    {
        printk(KERN_ERR "cope to user faile\n");
        return -2;
    }
    printk("user read:%s",itkuser);

	return 0;
}
//ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
ssize_t itkled_write(struct file *itkfile, const char __user *itkuser, size_t itklen, loff_t *itkloff)
{
    unsigned long ret = 0;
    
	printk(KERN_INFO "itk write\n");
    memset(itk_buf, 0, sizeof(itk_buf));
    ret = copy_from_user(itk_buf,itkuser,itklen);
    if(ret != 0)
    {
        printk(KERN_ERR "copy from user  faile\n");
        return -1;
    }
    printk(KERN_INFO "write len is %d\n",itklen);
    printk(KERN_INFO "user write string is %s\n",itk_buf);

	return 0;
}

//long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);
long itkled_ioctl(struct file *itkfile, unsigned int itkcmd, unsigned long itkarg)
{
    int gpio_val = -1;
    
    printk(KERN_INFO "you input cmd is = %d\n",itkcmd);

    switch(itkcmd)
    {
        case itkled_on:
            gk_gpio_set_out(15, 1);
            break;
        case itkled_off:
            gk_gpio_set_out(15, 0);
            break;
        case itkread_led:
            gpio_val = gk_gpio_get(15);
            if(gpio_val == 1)
                printk("LED is on\n");
            else
                printk("LED is off\n");
            break;
        default:
            printk("I do not you cmd");
            break;
    }
    
	return 0;
}
//int (*release) (struct inode *, struct file *);
int itkled_close(struct inode *itkinode, struct file *itkfile)
{
	printk(KERN_INFO "itk close\n");

	return 0;
}

static struct file_operations  itkled_miscfops = {
    .owner      = THIS_MODULE, ////指的是该操作属于当前的模块

	.open			= itkled_open,
	.read			= itkled_read,
	.write			= itkled_write,
	.unlocked_ioctl = itkled_ioctl,
	.release		= itkled_close,
};

static struct miscdevice itkmisc = {
    .minor      = itkmisc_mimor,
	.name       = ITKMISC,
	.fops       = &itkled_miscfops,
};


//申请
static int __init gk7102_led_init(void)
{
    int ret = 0;
    ret = misc_register(&itkmisc);
    if(ret != 0)
    {
        printk(KERN_ERR "misc register err\n");
        return -1;
    }

    return ret;
}

static void __exit gk7102_led_exit(void)
{
    misc_deregister(&itkmisc);
    printk(KERN_INFO "misc_deregister \n");
}

module_init(gk7102_led_init);
module_exit(gk7102_led_exit);


MODULE_LICENSE("GPL");


